package com.blacksheep.mtm.service.Impl;

import com.alibaba.fastjson.JSONObject;
import com.blacksheep.mtm.common.exception.XmallException;
import com.blacksheep.mtm.common.jedis.JedisClient;
import com.blacksheep.mtm.dao.*;
import com.blacksheep.mtm.pojo.common.DataTablesResult;
import com.blacksheep.mtm.pojo.manager.*;
import com.blacksheep.mtm.service.BindBoxService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class BindBoxServiceImpl implements BindBoxService {

    private static final Logger logger  = LoggerFactory.getLogger(BindBoxServiceImpl.class);

    @Autowired
    private TbBindBoxMapper bindBoxMapper;
    @Autowired
    private TbUserMapper userMapper;
    @Autowired
    private TbBoxDetailsMapper boxDetailsMapper;
    @Autowired
    private TbIceOutMapper outMapper;
    @Autowired
    private TbDeviceMapper deviceMapper;
    @Autowired
    private TbIceConfigMapper configMapper;
    @Autowired
    private JedisClient jedisClient;
    @Autowired
    private TbIceInMapper iceInMapper;

    @Override
    public DataTablesResult getList(int draw, int start, int length, int[] state, String search, String minDate, String maxDate, String orderCol, String orderDir) {
        DataTablesResult result=new DataTablesResult();
        PageHelper.startPage(start/length+1,length);
        List<TbBindBox> list = bindBoxMapper.selectList("%"+search+"%",state,minDate,maxDate,orderCol,orderDir);
        for (TbBindBox bindBox:list){
            String orderJson = jedisClient.get("BIND_ORDER_BOX_"+bindBox.getBoxCode());
            if (!StringUtils.isBlank(orderJson)){
                JSONObject object = JSONObject.parseObject(orderJson);
                String delivery  = object.getString("delivery");
                if (!StringUtils.isBlank(delivery)){
                    bindBox.setDeliveryer(delivery);
                }
            }
            List<String> detailsList = boxDetailsMapper.selectCodeListByBindId(bindBox.getId());
            bindBox.setDeviceCode(detailsList.toString());
        }
        PageInfo<TbBindBox> pageInfo=new PageInfo<>(list);
        result.setRecordsFiltered((int)pageInfo.getTotal());
        result.setDraw(draw);
        result.setData(list);
        return result;
    }

    @Override
    public TbBindBox add(TbBindBox box) {
        String username = SecurityUtils.getSubject().getPrincipal().toString();
        Long userId = userMapper.getUserIdByUsername(username);
        box.setOperator(userId.intValue());
        int result = bindBoxMapper.insertSelective(box);
        if (result<1){
            throw new XmallException("新增失败");
        }
        return box;
    }

    @Override
    public int alertState(int id, int state) {
        int result = bindBoxMapper.alertStateById(id,state);
        if (result<=0){
            throw  new XmallException("绑定失败");
        }
        return result;
    }

    @Override
    @Transactional
    public int addBatch(List<String> list) {
        String username = SecurityUtils.getSubject().getPrincipal().toString();
        Long userId = userMapper.getUserIdByUsername(username);
        TbBoxDetails boxDetails = null;
        TbIceConfig iceConfig = configMapper.selectByPrimaryKey(1);
        list = removeDuplicate(list);
        for (int i= 0;i<list.size();i++){
            String v = list.get(i);
            TbDevice device = deviceMapper.selectByCode(v);
            if (device == null){
                throw new XmallException("绑定失败,编码"+v+"错误");
            }
            if (StringUtils.equals(device.getType(),"BB")){
                TbBindBox bindBox = new TbBindBox();
                bindBox.setOperator(userId.intValue());
                bindBox.setUid(UUID.randomUUID().toString());
                bindBox.setBoxCode(v);
                bindBox.setState(1);
                bindBoxMapper.insertSelective(bindBox);
                if (bindBox.getId()<=0){
                    throw  new XmallException("绑定失败");
                }
                boxDetails = new TbBoxDetails();
                boxDetails.setBindId(bindBox.getId());
            }else{
                if (boxDetails !=null){
                    boxDetails.setDeviceCode(v);
                    boxDetails.setUuid(UUID.randomUUID().toString());
                    if(StringUtils.equals("BBP",device.getType()) || StringUtils.equals("LBP",device.getType()) ){
                        TbIceOut iceOut  = outMapper.selectLastOneByCode(v);
                        if (iceOut !=null){
                            long outTime = iceOut.getCreateTime();
                            if (new Date().getTime()  - outTime < (iceConfig.getIceTime()*60*1000)){
                                throw new XmallException("编码"+v+"冰块释冰时间不够");
                            }
                        }
                    }
                    int result = boxDetailsMapper.insertSelective(boxDetails);
                    if (result<=0){
                        throw  new XmallException("绑定失败");
                    }
                }
            }
        }
        for (int i= 0;i<list.size();i++){
            String v = list.get(i);
            if (StringUtils.equals("BBP",v.substring(0,3)) || StringUtils.equals("LBP",v.substring(0,3))){
                if (jedisClient.exists("ICE_IN_TIME_"+v)){
                    jedisClient.del("ICE_IN_TIME_"+v);
                }
            }
        }
        return list.size();
    }

    @Override
    @Transactional
    public int del(int id) {
        bindBoxMapper.deleteByPrimaryKey(id);
        boxDetailsMapper.deleteByBindId(id);
        return 0;
    }

    @Override
    public TbBoxDetails addDetails(int bindId, String code) {
        TbBoxDetails details = new TbBoxDetails();
        details.setUuid(UUID.randomUUID().toString());
        details.setDeviceCode(code);
        details.setBindId(bindId);
        int result = boxDetailsMapper.insertSelective(details);
        if (result<=0){
            throw  new XmallException("新增失败");
        }
        return null;
    }

    @Override
    @Transactional
    public int delDetails(Long[] ids) {
        for (long id:ids){
            boxDetailsMapper.deleteByPrimaryKey(id);
        }
        return 0;
    }

    @Override
    @Transactional
    public int unbind(int id) {
        String username = SecurityUtils.getSubject().getPrincipal().toString();
        Long userId = userMapper.getUserIdByUsername(username);
        TbBindBox bindBox = bindBoxMapper.selectByPrimaryKey(id);
        if (bindBox !=null){
            TbBindBox newBindBox = new TbBindBox();
            newBindBox.setId(id);
            newBindBox.setUnbindTime(new Date());
            newBindBox.setState(2);
            if (bindBoxMapper.updateByPrimaryKeySelective(newBindBox)<1){
                throw  new XmallException("解绑失败");
            };
            List<String> codes = boxDetailsMapper.selectCodeListByBindId(bindBox.getId());
            for (String v:codes){
                if (StringUtils.equals("BBP",v.substring(0,3)) || StringUtils.equals("LBP",v.substring(0,3))){
                    TbIceIn iceIn = new TbIceIn();
                    iceIn.setOperator(userId.intValue());
                    iceIn.setDeviceCode(v);
                    iceIn.setCreateTime(new Date().getTime());
                    if (iceInMapper.insertSelective(iceIn)<1){
                        throw  new XmallException("解绑失败");
                    }
                }
            }
            //冰包入库时间
            for (String v:codes){
                if (StringUtils.equals("BBP",v.substring(0,3)) || StringUtils.equals("LBP",v.substring(0,3))) {
                    String time = String.valueOf(new Date().getTime());
                    jedisClient.set("ICE_IN_TIME_"+v, time);
                    logger.info(v+"入库成功，时间戳："+time);
                }
            }
        }
        return 0;
    }

    @Override
    public int addRemark(int id, String remark) {
        int result  = bindBoxMapper.updateRemarkById(id,remark);
        return result;
    }

    private List<String> removeDuplicate(List<String> list){
        ArrayList<String> tempList = new ArrayList<>(list);
        LinkedHashSet<String> hashSet = new LinkedHashSet<>(tempList);
        ArrayList<String> result = new ArrayList<>(hashSet);
        return result.subList(0,result.size());
    }
}
